import React, { Component } from 'react'
import {
  Card,
  Select,
  Input,
  Button,
  Icon,
  Table,
  message,
  Cascader,
} from 'antd'
import { connect } from 'react-redux'
import Highlighter from 'react-highlight-words'

import { LinkButton } from '../../components/link-button'
import {
  reqProducts,
  reqSearchProducts,
  reqUpdateStatus,
  reqDeleteProduct,
  reqAllCategories,
  reqCategorys,
} from '../../api'
import { PAGE_SIZE } from '../../config'
import { setHashRouteParams } from '../../redux/actions'
import { linkToHashRouteWithParams, getReqData } from '../../utils'
import {
  formateDate,
  formateDateById,
  getTimeStampWithId,
} from '../../utils/dateUtils'

class ProductHome extends Component {
  constructor(props) {
    super(props)

    this.state = {
      total: 0, // 商品总数
      products: [], // 商品的数组
      loading: false,
      searchName: '', // 搜索的关键字
      searchType: 'name', // 根据哪个字段搜索
      flagInput: false,
      options: [
        {
          value: 'name',
          label: '按标题搜索',
          isLeaf: true,
        },
        {
          value: 'productDesc',
          label: '按分类搜索',
          isLeaf: false,
          // children: [
          //     {
          //         value: '00',
          //         label: '工作人员未读'
          //     },
          //     {
          //         value: '01',
          //         label: '客户不接电话'
          //     },
          //     {
          //         value: '02',
          //         label: '客户仅咨询'
          //     },
          //     {
          //         value: '03',
          //         label: '客户无意向'
          //     },
          //     {
          //         value: '04',
          //         label: '客户有意向'
          //     },
          // ],
        },
      ],
    }
  }

  /**
   * 初始化table的列的数组
   */
  initColumns = () => {
    const filters = this.filtersOfProducts()
    const columnsInfo = [
      {
        title: '标题',
        dataIndex: 'title',
        // ...this.getColumnSearchProps('title')
        // sorter: (a, b) => a.title.length - b.title.length,
      },
      {
        align: 'center',
        width: 200,
        title: '分类',
        dataIndex: 'cascaderText',
        filters,
        onFilter: (value, record) => record.cascaderText.indexOf(value) === 0,
      },
      {
        align: 'center',
        width: 150,
        title: '状态',
        // dataIndex: 'status', // 这里需要获取id，所以不能写status
        render: (product) => {
          let { status, _id } = product
          return (
            <span>
              <Button
                type={status === 1 ? 'primary' : 'danger'}
                onClick={() => this.updateStatus(_id, status === 1 ? 2 : 1)}
              >
                {status === 1 ? '已上线' : '已下线'}
              </Button>
            </span>
          )
        },
      },
      {
        align: 'center',
        width: 200,
        title: '最近操作时间',
        sorter: (a, b) => {
          const aId = a.lastTime === '' ? a._id.toString() : a.lastTime
          const bId = b.lastTime === '' ? b._id.toString() : b.lastTime
          return getTimeStampWithId(bId) * 1 - getTimeStampWithId(aId) * 1
        },
        render: (product) => {
          // const aId = product.lastTime === "" ? product._id.toString() : product.lastTime;
          if (product.lastTime === '')
            return formateDateById(product._id.toString())
          return formateDate(product.lastTime)
        },
      },
      {
        align: 'center',
        width: 100,
        title: '操作',
        render: (product) => (
          <span>
            <LinkButton
              onClick={() => {
                this.props.setHashRouteParams(product)
                this.props.history.push('/product/add-update')
              }}
            >
              修改
            </LinkButton>
            <LinkButton
              onClick={() => {
                const { _id } = product
                this.handleDelete(_id)
              }}
            >
              删除
            </LinkButton>
          </span>
        ),
      },
    ]
    this.setState({ columnsInfo })
  }

  /**
   * 获取指定页码的数据
   */
  getProducts = async (pageNum = 1) => {
    this.pageNum = pageNum // 让别的方法也能看到当前页
    const { searchName, flagInput, searchType } = this.state

    this.setState({ loading: true })

    // 如果是“按照标题搜索”，并且搜索关键字有值，说明需要搜索分页，否则就是一般分页
    // 如果是“按照分类搜索”，就不会管搜索关键字。
    let result

    // 如果能够使用搜索关键字
    if (!flagInput) {
      // 表示当前是“按照标题搜索”
      result =
        searchName !== ''
          ? await reqSearchProducts({
              pageNum,
              pageSize: PAGE_SIZE,
              searchName,
            })
          : await reqProducts(pageNum, PAGE_SIZE)
    } else {
      // 如果不能使用搜索关键字，表示当前是“按照分类搜索”
      result = await reqSearchProducts({
        pageNum,
        pageSize: PAGE_SIZE,
        searchType,
      })
    }

    const data = getReqData(result.result)
    // console.log('home 搜索结果', data);
    if (!data) return

    /**
     * todo 这里因为 聚合 的操作无法完成，正在等腾讯官方的工单。
     * 暂停使用聚合操作。
     */
    const { total, list } = data
    this.setState({ total, products: list, loading: false }, () => {
      this.initColumns()
    })
  }

  /**
   * 更新产品上架/下架信息
   */
  updateStatus = async (id, status) => {
    const { result } = await reqUpdateStatus(id, status)
    const flag = result.data.status === 0

    if (!flag) {
      message.error('更新上架/下架信息失败')
      return
    }
    message.success('更新成功')
    // 这里不知道更新第几页，定义 this.pageNum 记录当前的页数
    await this.getProducts(this.pageNum)
  }

  /**
   * 形成filters，注意清除重复的项
   */
  filtersOfProducts = () => {
    const { products } = this.state
    const result = products.map((item) => {
      const { cascaderText } = item

      return { text: cascaderText, value: cascaderText }
    })

    let tempRes = []

    result.forEach((itemR) => {
      result.forEach((temp) => {
        // 如果 tempRes 中存在元素，那么就看看有没有等于 itemR 的元素
        const flag =
          tempRes.length > 0
            ? tempRes.find((itemTemp) => itemTemp.text === itemR.text)
            : false
        // 如果找到了和自己相同的元素，并且 tempRes 中没有，那么就存起来。
        if (itemR.text === temp.text && !flag) tempRes.push(itemR)
      })
    })

    // console.log('tempRes', tempRes);

    return tempRes
  }

  getColumnSearchProps = (dataIndex) => ({
    filterDropdown: ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters,
    }) => (
      <div style={{ padding: 8 }}>
        <Input
          ref={(node) => {
            this.searchInput = node
          }}
          placeholder={`Search ${dataIndex}`}
          value={selectedKeys[0]}
          onChange={(e) =>
            setSelectedKeys(e.target.value ? [e.target.value] : [])
          }
          onPressEnter={() =>
            this.handleSearch(selectedKeys, confirm, dataIndex)
          }
          style={{ width: 188, marginBottom: 8, display: 'block' }}
        />
        <Button
          type="primary"
          onClick={() => this.handleSearch(selectedKeys, confirm, dataIndex)}
          icon="search"
          size="small"
          style={{ width: 90, marginRight: 8 }}
        >
          查找
        </Button>
        <Button
          onClick={() => this.handleReset(clearFilters)}
          size="small"
          style={{ width: 90 }}
        >
          重置
        </Button>
      </div>
    ),
    filterIcon: (filtered) => (
      <Icon type="search" style={{ color: filtered ? '#1890ff' : undefined }} />
    ),
    onFilter: (value, record) =>
      record[dataIndex].toString().toLowerCase().includes(value.toLowerCase()),
    onFilterDropdownVisibleChange: (visible) => {
      if (visible) {
        setTimeout(() => this.searchInput.select())
      }
    },
    render: (text) =>
      this.state.searchedColumn === dataIndex ? (
        <Highlighter
          highlightStyle={{ backgroundColor: '#ffc069', padding: 0 }}
          searchWords={[this.state.searchText]}
          autoEscape
          textToHighlight={text.toString()}
        />
      ) : (
        text
      ),
  })

  /**
   * 级联中的加载数据
   * @param selectedOptions this.state.options的其中一项
   */
  loadData = async (selectedOptions) => {
    let targetOption = selectedOptions[selectedOptions.length - 1]
    const { value } = targetOption
    targetOption.loading = true

    // console.log('selectedOptions', selectedOptions);

    // 如果是点击“按照分类搜索”，需要得到一级分类列表
    const parentId = 'productDesc' === value ? 0 : targetOption.value
    const { result } = await reqCategorys(parentId)
    targetOption.loading = false
    const data = getReqData(result)

    if (!data) return false

    // 如果是 parentId === 0 的，表示一级分类，那么 isLeaf: false
    if (data && data.length > 0)
      targetOption.children = data.map((item) => ({
        value: item._id,
        label: item.name,
        isLeaf: parentId !== 0,
      }))
    else targetOption.isLeaf = true

    // 找到 装修种类 这部分数据
    const decorationParentId = '5df0e327cdaeae3670403134'

    // 找到 其他 这部分的数据
    const otherParentId = '5df2097206c387360c5c29a0'

    if (!targetOption.children) return

    // 从 options 中清理出 装修种类+其他 这部分数据
    targetOption.children = targetOption.children.filter(
      (item) =>
        item.value !== decorationParentId && item.value !== otherParentId
    )

    // 注意这里，当点击“按分类搜索”。那么会将 Cascader 中的options传入给
    // 形参 selectedOptions，那么 selectedOptions 就相当于 state中的options
    // 这里修改targetOption就相当于修改 state中的options。
    // 最后为了保险起见，再使用下面这一步更新state。
    this.setState({ options: [...this.state.options] })
  }

  onChange = (value, selectedOptions) => {
    const length = value.length
    let searchType

    if (2 === length) {
      searchType = {
        pCategoryId: value[length - 1],
      }
    } else if (3 === length) {
      searchType = {
        pCategoryId: value[length - 1],
        categoryId: value[length - 2],
      }
    }

    // 禁用关键字输入框
    // 记录当前的品类id
    this.setState({
      flagInput: length !== 0 && value[0] === 'productDesc',
      searchType,
    })
  }

  /**
   * 删除文章
   */
  handleDelete = async (id) => {
    const { result } = await reqDeleteProduct(id)
    const data = getReqData(result)
    if (!data) {
      message.error('删除文章出错')
      return null
    }
    await this.getProducts(this.pageNum)
  }

  handleSearch = (selectedKeys, confirm, dataIndex) => {
    confirm()
    this.setState({
      searchText: selectedKeys[0],
      searchedColumn: dataIndex,
    })
  }

  handleReset = (clearFilters) => {
    clearFilters()
    this.setState({ searchText: '' })
  }

  componentDidMount() {
    this.getProducts(1)
    // this.initOptions();
  }

  render() {
    let {
      products,
      total,
      loading,
      searchName,
      columnsInfo,
      options,
      flagInput,
    } = this.state

    const title = (
      <div>
        <Cascader
          options={options}
          loadData={this.loadData}
          defaultValue={['name']}
          placeholder={'请选择'}
          onChange={this.onChange}
          changeOnSelect
          style={{ width: 300 }}
        />

        <Input
          placeholder="关键字"
          disabled={flagInput}
          style={{ width: 100, margin: '0 15px' }}
          value={searchName}
          onChange={(e) => this.setState({ searchName: e.target.value })}
        />
        <Button
          type="primary"
          onClick={async () => {
            await this.getProducts()
          }}
        >
          搜索
        </Button>
      </div>
    )
    const extra = (
      <Button
        type="primary"
        onClick={() => {
          // this.props.history.push('/product/add-update')
          linkToHashRouteWithParams(this, '/product/add-update')
        }}
      >
        <Icon type="plus" />
        添加图片/文章
      </Button>
    )
    return (
      <Card title={title} extra={extra}>
        <Table
          loading={loading}
          bordered
          rowKey="_id"
          dataSource={products}
          columns={columnsInfo}
          pagination={{
            current: this.pageNum, // 搜索的时候会重置 this.pageNum
            defaultPageSize: PAGE_SIZE,
            showQuickJumper: true,
            total,
            onChange: this.getProducts,
          }}
          locale={{ filterConfirm: '确定', filterReset: '重置' }}
        />
      </Card>
    )
  }
}

export default connect(
  (state) => ({}),
  { setHashRouteParams } // 这个是在 this.props.setHeadTitle 中读取。
)(ProductHome)
